/*************************************************************************
	> File Name: watchdog.cpp
	> Author: xuwenlong
	> Mail: myxuan475@126.com 
	> Created Time: 2018年09月21日 星期五 10时45分12秒
 ************************************************************************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <utils/logger.h>
#include "watchdog.h"
#include <transport/globalmsg.h>

#if defined(HTNICE_K4) || defined(HTNICE_OLDK4)
#define FEED_WATCHDOG	{char buf = '1'; write(fdw,&buf,1);}while(0)
#define CLOSE_WDT {char buf = 'V'; write(fdw,&buf,1);close(fdw);}while(0)
#define ENABLE_WDT

#elif defined(HTNICE_K2)

#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>
#define	WDIOC_SETMSTIMER	0xfedcba
#define	WDIOC_GETMSTIMER	0xfedcb9

int timer_val,wdt_val;
char buf;

#define REBOOTTIME	120	//看门狗复位时间
#define ENABLE_WDT	{\
    timer_val = (REBOOTTIME+1)*1000;\
    wdt_val = REBOOTTIME; \
    ioctl(fdw,WDIOC_SETTIMEOUT,&wdt_val); \
    ioctl(fdw,WDIOC_SETMSTIMER,&timer_val); \
    }while(0)//开启看门狗
#define FEED_WATCHDOG	{ioctl(fdw,WDIOC_KEEPALIVE,0);}while(0)	//喂狗
#define CLOSE_WDT {buf = 'V'; write(fdw,&buf,1);close(fdw);}while(0)	//关闭看门狗
#else
#define FEED_WATCHDOG	{}while(0)
#define CLOSE_WDT {}while(0)
#define ENABLE_WDT
#endif
int fdw = -1;

WatchDog::WatchDog():
    m_pTimer(new Timer("watchdog",this))
{
    OpenDog();
    m_pTimer->Start(1000,kPeriodic);
}

WatchDog::~WatchDog()
{
    CloseDog();
    m_pTimer->Stop();
    delete m_pTimer;
}

void WatchDog::RunTimer()
{
    FeedDog();
    if (!GetMsgStatus(DAS_BUF_DOG)) {
//        m_icheck = 0;
    }
    else {
//        m_icheck++;
        if (GetDogCheck() > 240) {
            time_t now = time(NULL);
            S64 secs = (S64)(60*15);

            //修正时间
//            S64 amend = (secs+1)/5;
            S64 wait = secs-((S64)(now))%secs;

            if (wait >= 300 && wait < 360) {
                LOG_ERR("something locked,force exit!");
                exit(0);
            }
        }
    }
}

void WatchDog::OpenDog() {
    if((fdw = open("/dev/watchdog",O_RDWR))==-1)
    {
        LOG_ERR("Can not open /dev/watchdog");
//        exit(1);
        return;
    }

    ENABLE_WDT;
}

void WatchDog::FeedDog() {
    if (fdw!=-1) {
        FEED_WATCHDOG;
    }
}

void WatchDog::CloseDog() {
    CLOSE_WDT;
}

